package org.xmdl.silk.wrap;

import java.util.List;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.xmdl.silk.Method;
import org.xmdl.silk.Program;
import org.xmdl.silk.Statement;
import org.xmdl.silk.impl.ProgramImpl;
import org.xmdl.silk.visit.Visitor;

public class ProgramWrap extends ProgramImpl implements Wrapped {

	private final Program wrap;
	
	private EList<Method> wMethods;

	private EList<Statement> wStatements;

	public ProgramWrap(Program wrap) {
		this.wrap = wrap;
	}

	@Override
	public EList<Method> getMethods() {
		if (wMethods == null) {
			wMethods = new BasicEList<Method>();
			for (Method c : wrap.getMethods()) {
				Method cw = WrapUtils.method(c);
				wMethods.add(cw);
			}
		}
		return wMethods;
	}

	@Override
	public EList<Statement> getStatements() {
		if (wStatements == null) {
			wStatements = new BasicEList<Statement>();
			for (Statement c : wrap.getStatements()) {
				Statement cw = WrapUtils.statement(c);
				wStatements.add(cw);
			}
		}
		return wStatements;
	}

	public boolean accept(Visitor visitor)
	{
		if (visitor.visitEnter(this)) {
			final List<Method> methods = getMethods();
			for (Method child : methods) {
				if (!((Wrapped)child).accept(visitor))
					break;
			}
			final List<Statement> statements = getStatements();
			for (Statement child : statements) {
				if (!((Wrapped)child).accept(visitor))
					break;
			}
		}
		boolean result = visitor.visitLeave(this);
		return result;
	}
}
